Android Splash Screen
A guide to add animated and still splash screen for android
Ref: https://developer.android.com/develop/ui/views/launch/splash-screen
Designing The Logo
You can experiment with different sizes, but make sure to test on both old and new Android devices with varying resolutions and screen sizes.
I found that a canvas (viewport) sized at 432x432 works best. For this example, an icon size of 200x200 centered inside the canvas provides the best fit. However, this may vary depending on the icon’s shape.
When designing your logo using Figma, you can use an extension to export your design as an XML Android Vector Drawable.
For the animated version, you can code it manually using Android Studio. Alternatively, you can create the animation using Lottie or a simple online tool like Shapeshifter.
Creating The App Logo
Assuming you have an SVG for your app logo, we need it to create the following xml files at android/app/src/main/res/drawable:
splash_logo.xml
Go to android/app/src/main/res/drawable and create splash_logo.xml.
A vector of your app logo (not animated) for older android devices that doesn’t support animated splash screen.
We are using dynamic colors in this example @color/bag @color/pins for light and dark themes, we will setup them later here.
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="432dp" android:height="432dp" android:viewportWidth="432" android:viewportHeight="432"> <path android:fillColor="@color/bag" android:pathData="M181.692 155.695C181.692 136.699 197.184 121.226 216.252 121.226C235.319 121.226 250.811 136.703 250.811 155.695V164.967H261.06V155.695C261.06 131.064 240.969 111 216.252 111C191.534 111 171.443 131.064 171.443 155.695L171.447 164.967H181.692V155.695Z" /> <path android:fillColor="@color/bag" android:pathData="M136.876 186.971C138.849 174.31 149.752 164.974 162.566 164.974H269.869C282.714 164.974 293.634 174.354 295.572 187.052L311.083 288.7C313.669 305.651 300.55 320.924 283.403 320.924H148.702C131.519 320.924 118.39 305.59 121.036 288.612L136.876 186.971Z" /> <path android:fillColor="@color/pins" android:pathData="M171.462 164.974H181.719V195.908C181.719 195.908 187.108 195.908 190.561 195.908C193.391 195.908 195.625 198.147 195.625 200.997C195.625 203.847 193.411 206.072 190.561 206.086C179.637 206.086 173.507 206.086 162.582 206.086C159.785 206.086 157.505 203.794 157.519 200.997C157.533 198.2 159.786 195.936 162.582 195.908C166.05 195.908 171.462 195.908 171.462 195.908V164.974Z" /> <path android:fillColor="@color/pins" android:pathData="M250.855 164.974H261.112V195.908C261.112 195.908 266.501 195.908 269.954 195.908C272.784 195.908 275.018 198.147 275.018 200.997C275.018 203.847 272.804 206.072 269.954 206.086C259.029 206.086 252.9 206.086 241.975 206.086C239.178 206.086 236.898 203.794 236.912 200.997C236.926 198.2 239.178 195.936 241.975 195.908C245.442 195.908 250.855 195.908 250.855 195.908V164.974Z" /></vector>splash_animated.xml
An animated version of your app logo.
For that, you can code it manually using Android Studio. Alternatively, you can create the animation using Lottie or a simple online tool like Shapeshifter.
The output file should look something like this
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable"> <!-- vector: where paths are grouped --> </aapt:attr>
<!-- targets with each target has an animation --></animated-vector>Creating splash screen
style(default for older devices)- Go to
android/app/src/main/res/values/styles.xml. - Here we are using
@drawable/splash_logoa static vector.
<resources><style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar"><item name="android:editTextBackground">@drawable/rn_edit_text_material</item><!-- Only when facing issues --><item name="android:windowBackground">@android:color/transparent</item><item name="android:statusBarColor">@android:color/transparent</item></style><!-- Splash Screen --><style name="Theme.App.Starting" parent="Theme.SplashScreen"><item name="windowSplashScreenBackground">@color/background</item><item name="windowSplashScreenAnimatedIcon">@drawable/splash_logo</item><item name="postSplashScreenTheme">@style/AppTheme</item></style></resources>- Go to
Using splash screen style
- Go to
android/app/src/mainAndroidManifest.xmland use the style we created above. - Add or replace
android:themeattribute in theapplicationtag with splash screen style name.
<application android:theme="@style/Theme.App.Starting">- Go to
Using the animated version for devices that support it.
- Create
android/app/src/main/res/values-v31/styles.xml. - Here we are using
@drawable/splash_animatedthe animated version of the logo.
<?xml version="1.0" encoding="utf-8"?><resources><style name="Theme.App.Starting" parent="Theme.SplashScreen"><item name="windowSplashScreenBackground">@color/background</item><item name="windowSplashScreenAnimatedIcon">@drawable/splash_animated</item><item name="android:windowSplashScreenAnimationDuration">1000</item><item name="postSplashScreenTheme">@style/AppTheme</item></style></resources>- Create
Dynamic colors
Dynamic colors to change your splash screen colors to match user’s device color scheme.
- For light theme
android/app/src/main/res/values/colors.xml
<resources><color name="background">#FFFFFF</color><color name="bag">#1A191F</color><color name="pins">#FFFFFF</color></resources>- For dark theme
android/app/src/main/res/values-night/colors.xml
<resources><color name="background">#1A191F</color><color name="bag">#FFFFFF</color><color name="pins">#1A191F</color></resources>- For light theme
The Code Part
Preparing The Splash Screen
Add splash screen package:
- Go to
android/app/build.gradleand the following todependenciesblock
dependencies {// Ensure you are using the current latest versionimplementation("androidx.core:core-splashscreen:1.2.0-beta01")}- Go to
Go to
android/app/src/main/java/com/<AppName>/MainActivity.kt// import thisimport androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen// optional - for hiding the splash screen manually// require creating a native module (later in this guide)import com.<AppName>.hideSplashScreen.HideSplashScreenModule// optional for exit animationsimport android.animation.AnimatorSetimport android.animation.ObjectAnimatorimport android.view.Viewimport androidx.core.animation.doOnEndclass MainActivity : ReactActivity() {override fun onCreate(savedInstanceState: Bundle?) {// add this (before super.onCreate)installSplashScreen().apply {// optional - for hiding the splash screen manually// require creating a native module (later in this guide)setKeepOnScreenCondition { NativeSplashScreenModule.keepOn }// optional - exit animationssetOnExitAnimationListener { screen ->val duration = 200Lval zoomInX = ObjectAnimator.ofFloat(screen.iconView, View.SCALE_X, 1f, 5f)zoomInX.duration = durationval zoomInY = ObjectAnimator.ofFloat(screen.iconView, View.SCALE_Y, 1f, 5f)zoomInY.duration = durationval fadeOut = ObjectAnimator.ofFloat(screen.view, View.ALPHA, 1f, 0f)fadeOut.duration = durationAnimatorSet().apply {playTogether(zoomInX, zoomInY, fadeOut)doOnEnd { screen.remove() }start()}}}super.onCreate(null)}// ---}
Hiding the splash screen manually
To be able to hide the splash screen from JavaScript we need to create a Native module.
Create
specs/NativeSplashScreenin the root of your project.import { TurboModuleRegistry } from "react-native";import type { TurboModule } from "react-native";export interface Spec extends TurboModule {hide(): void;}export default TurboModuleRegistry.getEnforcing<Spec>("NativeSplashScreen");Configure Codegen by adding the following to your project
package.json, then runcd android && ./gradlew generateCodegenArtifactsFromSchema. This is automatically run when you build your Android application.
"codegenConfig": { "name": "NativeSplashScreenSpec", "type": "modules", "jsSrcsDir": "specs", "android": { "javaPackageName": "com.nativeSplashScreen" } },Go to
android/app/src/main/java/com/nativeSplashScreenand createNativeSplashScreenModule.ktpackage com.nativeSplashScreenimport com.facebook.react.bridge.ReactApplicationContextclass NativeSplashScreenModule(reactContext: ReactApplicationContext) :NativeSplashScreenSpec(reactContext) {override fun getName() = NAMEoverride fun hide() {keepOn = false}companion object {const val NAME = "NativeSplashScreen"var keepOn = true}}In the same directory create
NativeSplashScreenPackage.ktpackage com.nativeSplashScreenimport com.facebook.react.BaseReactPackageimport com.facebook.react.bridge.NativeModuleimport com.facebook.react.bridge.ReactApplicationContextimport com.facebook.react.module.model.ReactModuleInfoimport com.facebook.react.module.model.ReactModuleInfoProviderclass NativeSplashScreenPackage : BaseReactPackage() {override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? =if (name == NativeSplashScreenModule.NAME) {NativeSplashScreenModule(reactContext)} else {null}override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {mapOf(NativeSplashScreenModule.NAME to ReactModuleInfo(name = NativeSplashScreenModule.NAME,className = NativeSplashScreenModule.NAME,canOverrideExistingModule = false,needsEagerInit = false,isCxxModule = false,isTurboModule = true))}}Go to
android/app/src/main/java/com/<AppName>/MainApplication.ktto register the native module we have created.import com.nativeSplashScreen.NativeSplashScreenPackage // import this// ---class MainApplication : Application(), ReactApplication {override val reactNativeHost: ReactNativeHost = object : DefaultReactNativeHost(this) {override fun getPackages(): List<ReactPackage> = PackageList(this).packages.apply {add(NativeSplashScreenPackage()) // add this}// ---Call it from JavaScript
import NativeSplashScreen from "../specs/NativeSplashScreen";// when your app is fully loaded call this to hide the splash screenNativeSplashScreen.hide();NoteIf the screen went black after the splash screen is shown it might be due to the
debugbuild, make sure to test thereleasebuild.